package com.michale.system.service.impl;

import com.michale.common.constants.RedisCacheConstant;
import com.michale.common.domain.operate.UserOnlineEntity;
import com.michale.common.domain.security.LoginUserDetail;
import com.michale.common.utils.String.StringUtils;
import com.michale.common.utils.redis.RedisUtils;
import com.michale.system.service.CacheService;
import com.michale.system.service.UserOnlineService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * @author Michale
 * @apiNote 在线用户 业务层
 */
@Slf4j
@Service("userOnlineService")
public class UserOnlineServiceImpl implements UserOnlineService {

    @Resource
    private RedisUtils redisUtils;
    @Resource
    private CacheService cacheService;

    /**
     * 通过登录地址查询信息
     *
     * @param ipAddress       登录地址
     * @param loginUserDetail 用户信息
     * @return 在线用户信息
     */
    @Override
    public UserOnlineEntity selectOnlineByIpAddress(String ipAddress, LoginUserDetail loginUserDetail) {
        if (StringUtils.equals(ipAddress, loginUserDetail.getIpAddress())) {
            return loginUserToUserOnline(loginUserDetail);
        }
        return null;
    }

    /**
     * 通过用户名称查询信息
     *
     * @param userName        用户名称
     * @param loginUserDetail 用户信息
     * @return 在线用户信息
     */
    @Override
    public UserOnlineEntity selectOnlineByUserName(String userName, LoginUserDetail loginUserDetail) {
        if (StringUtils.equals(userName, loginUserDetail.getUsername())) {
            return loginUserToUserOnline(loginUserDetail);
        }
        return null;
    }

    /**
     * 通过登录地址/用户名称查询信息
     *
     * @param ipAddress       登录地址
     * @param userName        用户名称
     * @param loginUserDetail 用户信息
     * @return 在线用户信息
     */
    @Override
    public UserOnlineEntity selectOnlineByInfo(String ipAddress, String userName, LoginUserDetail loginUserDetail) {
        if (StringUtils.equals(ipAddress, loginUserDetail.getIpAddress()) && StringUtils.equals(userName, loginUserDetail.getUsername())) {
            return loginUserToUserOnline(loginUserDetail);
        }
        return null;
    }

    /**
     * 设置在线用户信息
     *
     * @param loginUserDetail 用户信息
     * @return 在线用户
     */
    @Override
    public UserOnlineEntity loginUserToUserOnline(LoginUserDetail loginUserDetail) {
        if (StringUtils.isNull(loginUserDetail) || StringUtils.isNull(loginUserDetail.getUserEntity())) {
            return null;
        }
        UserOnlineEntity userOnlineEntity = new UserOnlineEntity();
        userOnlineEntity.setTokenId(loginUserDetail.getToken());
        userOnlineEntity.setUserName(loginUserDetail.getUsername());
        userOnlineEntity.setIpAddress(loginUserDetail.getIpAddress());
        userOnlineEntity.setLoginLocation(loginUserDetail.getLoginLocation());
        userOnlineEntity.setLoginTime(loginUserDetail.getLoginTime());
        userOnlineEntity.setBrowser(loginUserDetail.getBrowser());
        userOnlineEntity.setOs(loginUserDetail.getOs());
        if (StringUtils.isNotNull(loginUserDetail.getUserEntity().getDeptEntity())) {
            userOnlineEntity.setDeptName(loginUserDetail.getUserEntity().getDeptEntity().getDeptName());
        }
        return userOnlineEntity;
    }

    /**
     * 查询-在线用户
     *
     * @param ipAddress IP地址
     * @param userName  用户名
     * @return 在线用户列表
     */
    @Override
    public List<UserOnlineEntity> onlineList(String ipAddress, String userName) {
        Collection<String> loginTokenKey = redisUtils.keys(RedisCacheConstant.LOGIN_TOKEN_KEY + "*");
        List<UserOnlineEntity> userOnlineList = new ArrayList<>();
        for (String key : loginTokenKey) {
            LoginUserDetail loginUserDetail = redisUtils.getCacheObject(key);
            if (StringUtils.isNotEmpty(ipAddress) && StringUtils.isNotEmpty(userName)) {
                if (StringUtils.equals(ipAddress, loginUserDetail.getIpAddress()) && StringUtils.equals(userName, loginUserDetail.getUsername())) {
                    userOnlineList.add(selectOnlineByInfo(ipAddress, userName, loginUserDetail));
                }
            } else if (StringUtils.isNotEmpty(ipAddress)) {
                if (StringUtils.equals(ipAddress, loginUserDetail.getIpAddress())) {
                    userOnlineList.add(selectOnlineByIpAddress(ipAddress, loginUserDetail));
                }
            } else if (StringUtils.isNotEmpty(userName)) {
                if (StringUtils.equals(userName, loginUserDetail.getUsername())) {
                    userOnlineList.add(selectOnlineByUserName(ipAddress, loginUserDetail));
                }
            } else {
                userOnlineList.add(loginUserToUserOnline(loginUserDetail));
            }
        }
        /*list集合进行降序排序*/
        Collections.reverse(userOnlineList);
        userOnlineList.removeAll(Collections.singleton(null));
        return userOnlineList;
    }

    /**
     * 强制退出
     *
     * @param tokenId 会话ID
     */
    @Override
    public void forceLogout(String tokenId) {
        LoginUserDetail loginUserDetail = redisUtils.getCacheObject(RedisCacheConstant.LOGIN_TOKEN_KEY + tokenId);
        cacheService.clearCacheKey(RedisCacheConstant.LOGIN_KEY + loginUserDetail.getUsername());
        cacheService.clearCacheKey(RedisCacheConstant.LOGIN_TOKEN_KEY + tokenId);
    }
}
